package org.glut.wechat.chat.service.impl;

import jakarta.annotation.Resource;
import org.glut.wechat.chat.domain.Group;
import org.glut.wechat.chat.service.IGroupService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class IGroupServiceImpl implements IGroupService {

    // Redis键前缀（避免key冲突）
    private static final String GROUP_KEY_PREFIX = "group:";           // 群基本信息 key: group:{groupId}
    private static final String GROUP_MEMBERS_PREFIX = "group:members:"; // 群成员关系 key: group:members:{groupId}
    private static final String USER_GROUPS_PREFIX = "user:groups:";    // 用户所属群关系 key: user:groups:{userId}

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public String createGroup(String ownerId, String groupName) {
        // 生成群ID（前缀group_区分用户ID）
        String groupId = "group_" + UUID.randomUUID().toString().substring(0, 8);

        // 构建群信息
        Group group = new Group();
        group.setId(groupId);
        group.setGroupName(groupName);
        group.setOwnerId(ownerId);
        group.setCreateTime(new Date());

        // 1. 存储群基本信息（Hash结构，便于单独更新字段）
        redisTemplate.opsForHash().putAll(
                GROUP_KEY_PREFIX + groupId,
                new HashMap<String, Object>() {{
                    put("id", group.getId());
                    put("groupName", group.getGroupName());
                    put("ownerId", group.getOwnerId());
                    put("createTime", group.getCreateTime().getTime()); // 存储时间戳便于序列化
                }}
        );
        // 设置过期时间（可选，根据业务需求）
        redisTemplate.expire(GROUP_KEY_PREFIX + groupId, 30, TimeUnit.DAYS);

        // 2. 添加群主到群成员（Set结构，自动去重）
        redisTemplate.opsForSet().add(GROUP_MEMBERS_PREFIX + groupId, ownerId);
        redisTemplate.expire(GROUP_MEMBERS_PREFIX + groupId, 30, TimeUnit.DAYS);

        // 3. 维护用户-群关系（反向索引，便于查询用户所属群）
        redisTemplate.opsForSet().add(USER_GROUPS_PREFIX + ownerId, groupId);
        redisTemplate.expire(USER_GROUPS_PREFIX + ownerId, 30, TimeUnit.DAYS);

        return groupId;
    }

    @Override
    public boolean inviteMember(String groupId, String inviterId, String beInvitedUserId) {
        // 1. 校验群是否存在
        if (!redisTemplate.hasKey(GROUP_KEY_PREFIX + groupId)) {
            return false;
        }

        // 2. 校验邀请者是否为群成员
        Boolean inviterIsMember = redisTemplate.opsForSet().isMember(GROUP_MEMBERS_PREFIX + groupId, inviterId);
        if (inviterIsMember == null || !inviterIsMember) {
            return false;
        }

        // 3. 校验被邀请者是否已在群内
        Boolean beInvitedIsMember = redisTemplate.opsForSet().isMember(GROUP_MEMBERS_PREFIX + groupId, beInvitedUserId);
        if (beInvitedIsMember != null && beInvitedIsMember) {
            return false;
        }

        // 4. 添加被邀请者到群成员
        redisTemplate.opsForSet().add(GROUP_MEMBERS_PREFIX + groupId, beInvitedUserId);

        // 5. 更新被邀请者的群列表
        redisTemplate.opsForSet().add(USER_GROUPS_PREFIX + beInvitedUserId, groupId);
        return true;
    }

    @Override
    public Set<String> getGroupMembers(String groupId) {
        // 从Set中获取群成员（转换为String类型）
        Set<Object> membersObj = redisTemplate.opsForSet().members(GROUP_MEMBERS_PREFIX + groupId);
        if (membersObj == null || membersObj.isEmpty()) {
            return Collections.emptySet();
        }
        return membersObj.stream()
                .map(String::valueOf)
                .collect(Collectors.toSet());
    }

    @Override
    public List<Group> getUserGroups(String userId) {
        // 1. 获取用户所属的所有群ID
        Set<Object> groupIdsObj = redisTemplate.opsForSet().members(USER_GROUPS_PREFIX + userId);
        if (groupIdsObj == null || groupIdsObj.isEmpty()) {
            return Collections.emptyList();
        }

        // 2. 批量查询群信息
        List<Group> userGroups = new ArrayList<>();
        for (Object groupIdObj : groupIdsObj) {
            String groupId = String.valueOf(groupIdObj);
            Map<Object, Object> groupHash = redisTemplate.opsForHash().entries(GROUP_KEY_PREFIX + groupId);

            if (!groupHash.isEmpty()) {
                Group group = new Group();
                group.setId(String.valueOf(groupHash.get("id")));
                group.setGroupName(String.valueOf(groupHash.get("groupName")));
                group.setOwnerId(String.valueOf(groupHash.get("ownerId")));
                group.setCreateTime(new Date(Long.parseLong(String.valueOf(groupHash.get("createTime")))));
                userGroups.add(group);
            }
        }
        return userGroups;
    }

    @Override
    public Group getGroupById(String groupId) {
        Map<Object, Object> groupHash = redisTemplate.opsForHash().entries(GROUP_KEY_PREFIX + groupId);
        if (groupHash.isEmpty()) {
            return null;
        }

        // 从Hash结构中构建Group对象
        Group group = new Group();
        group.setId(String.valueOf(groupHash.get("id")));
        group.setGroupName(String.valueOf(groupHash.get("groupName")));
        group.setOwnerId(String.valueOf(groupHash.get("ownerId")));
        group.setCreateTime(new Date(Long.parseLong(String.valueOf(groupHash.get("createTime")))));
        return group;
    }
}
